package site.teamo.biu.net.common.handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import site.teamo.biu.net.common.constant.ChannelAttributeKey;
import site.teamo.biu.net.common.util.HostPort;

@Slf4j
public class ExceptionHandler extends ChannelDuplexHandler {
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        channelClose(ctx.channel());
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            channelClose(ctx.channel());
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        channelClose(ctx.channel());
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        channelClose(ctx.channel());
    }

    private void channelClose(Channel channel) {
        HostPort hostPort = channel.attr(ChannelAttributeKey.DESTINATION_INFO).get();
        Channel target = channel.attr(ChannelAttributeKey.TARGET_CHANNEL).get();
        if (target == null) {
            channel.close();
        } else {
            if (hostPort == null) {
                hostPort = target.attr(ChannelAttributeKey.DESTINATION_INFO).get();
            }
            channel.close();
            target.close();
        }
        if (hostPort != null) {
            log.debug("使用{}与目标{}:{}建立的连接已关闭", hostPort.protocol(), hostPort.host(), hostPort.port());
        }
    }
}
